<?php
/**
 * NP_WPSandBox
 *
 * This file is the plugin which makes sure that "SandBox" of "WordPress" can be used by "NucleusCMS".
 * Please see a {@link http://www.plaintxt.org/themes/sandbox/ link destination} about details of "SandBox".
 *
 * @author shizuki <shizuki@kinezumi.net>
 * @license http://nucleuscms.org/license.txt GNU General Public License
 * @copyright Copyright (C) 2002-2009 The Nucleus Group
 * @version $Id: NP_WPSandBox.php 67 2009-03-09 04:35:03Z shizuki17xx $
 */

class NP_WPSandBox extends NucleusPlugin
{

// {{{ propaties

/**
 * Class properties
 */

/**
 * @name $contentType
 * @var string
 */
static protected $contentType;

/**
 * @name $skin
 * @var object Current SKIN obj
 */
static protected $skin;

/**
 * @name $skinType
 * @var string
 */
static protected $skinType;

/**
 * @name $page
 * @var int current page No.
 */
static protected $page;

/**
 * @name $parser
 * @var object SandBoxParser Class
 */
static protected $parser;

// }}}
// {{{ constructor

/**
 * Construct
 */

	// {{{ __construct()

	/**
	 * Construct
	 *
	 * Plugin initialize
	 */
	public function __construct()
	{
		self::$contentType = 'text/html';
		self::$skin        = null;
		self::$skinType    = '';
		self::$page        = 0;
		if (!class_exists('SandBoxParser')) {
			// include parser class
			include_once(self::getDirectory() . 'SandBoxParser.inc.php');
			self::$parser  = new SandBoxParser;
		}
		if (!defined('')) {
			self::includeLanguageFile();
		}
	}

	// }}}

// }}}
// {{{ class auto load

/**
 * Auto load
 */

	// {{{ __autoload()

	/**
	 * Construct
	 *
	 * Plugin initialize
	 */
	public function __autoload($className)
	{
		global $DIR_LIBS;
		include_once($DIR_LIBS . $className . '.php');
	}

	// }}}

// }}}
// {{{ Plugin requier methodes

/**
 * Over ride to PLUGIN class
 */

	// {{{getName()

	/**
	 * Plugin name
	 *
	 * @return string
	 */
	public function getName()
	{
		return 'Sandbox';
	}

	// }}}
	// {{{ getAuthor()

	/**
	 * Plugin author
	 *
	 * @return string
	 */
	public function getAuthor()
	{
		return 'shizuki';
	}

	// }}}
	// {{{ getURL()

	/**
	 * Plugin download site
	 *
	 * @return string
	 */
	public function getURL()
	{
		return 'http://shizuki.kinezumi.net/';
	}

	// }}}
	// {{{ getVersion()

	/**
	 * Plugin version
	 *
	 * @return string
	 */
	public function getVersion()
	{
		return '1.0.1';
	}

	// }}}
	// {{{ getMinNucleusVersion()

	/**
	 * Requier Nucleus version
	 *
	 * @return string
	 */
	public function getMinNucleusVersion()
	{
		return '340';
	}

	// }}}
	// {{{ getDescription()

	/**
	 * Plugin description
	 *
	 * @return string
	 */
	public function getDescription()
	{
		return _NP_WPSANDBOX_DESCRIPTION;
	}

	// }}}
	// {{{ supportsFeature($what)

	/**
	 * Plugin support feature
	 *
	 * @param string Nucleus feature
	 * @return bool
	 */
	public function supportsFeature($what)
	{
		switch($what) {
			case 'SqlTablePrefix':
				return 1;
			default:
				return 0;
		}
	}

	// }}}
	// {{{ getEventList()

	/**
	 * List of the events used by plugin
	 *
	 * @return array
	 */
	public function getEventList()
	{
		$events = array('InitSkinParse',
						'PreSendContentType',
						'TemplateExtraFields',
						'WPSandBoxPrePageHead',
						'WPSandBoxPrePageFoot',
						'WPSandBoxDynamicSidebar',
						'WPSandBoxWPMETAEmulate',);
		return $events;
	}

	// }}}
	// {{{ install()

	/**
	 * Execute plugin installation
	 *
	 * Create plugin option for each blog skin setteings.
	 */
	public function install()
	{
		$nametypeSelect  = _EBLOG_NAME . '|name|' . _EBLOG_SHORTNAME . '|shortname';
		$orderbySelect   = _EBLOG_NAME . '|name|' . _EBLOG_BLOGID . '|number|'
						 . _EBLOG_SHORTNAME . '|shortname|' . _EBLOG_DESC . '|description';
		$directionSelect = _NP_WPSANDBOX_DIRECTIONORDER_DESC . '|desc|' . _NP_WPSANDBOX_DIRECTIONORDER_ASC . '|asc';
		$bookmarkList    = file_get_contents(self::getDirectory() . 'defaultLinkList.txt');
		if (_CHARSET != 'UTF-8') {
			$bookmarkList = mb_convert_encoding($bookmarkList, _CHARSET, 'UTF-8');
		}
		$syndicateList   = file_get_contents(self::getDirectory() . 'defaultFeedList.txt');
		if (_CHARSET != 'UTF-8') {
			$syndicateList = mb_convert_encoding($syndicateList, _CHARSET, 'UTF-8');
		}
		self::createBlogOption('sandboxSkin',      _NP_WPSANDBOX_BLOGOPTION_SANDBOX,  'text',     'Sandbox');
		self::createBlogOption('showPageList',     _NP_WPSANDBOX_BLOGOPTION_PAGELIST, 'yesno',    'yes');
		self::createBlogOption('showBlogList',     _NP_WPSANDBOX_BLOGOPTION_BLOGLIST, 'yesno',    'yes');
		self::createBlogOption('showCategoryList', _NP_WPSANDBOX_BLOGOPTION_CATELIST, 'yesno',    'yes');
		self::createBlogOption('showArchoveList',  _NP_WPSANDBOX_BLOGOPTION_ARCVLIST, 'yesno',    'yes');
		self::createBlogOption('showSearchBox',    _NP_WPSANDBOX_BLOGOPTION_SARCHBOX, 'yesno',    'yes');
		self::createBlogOption('showBookmarkList', _NP_WPSANDBOX_BLOGOPTION_BKMKLIST, 'yesno',    'yes');
		self::createBlogOption('showFeedsList',    _NP_WPSANDBOX_BLOGOPTION_FEEDLIST, 'yesno',    'yes');
		self::createBlogOption('showMetaBox',      _NP_WPSANDBOX_BLOGOPTION_METABOX,  'yesno',    'yes');
		self::createBlogOption('bnametype',        _NP_WPSANDBOX_BLOGOPTION_BNAMTYPE, 'select',   'name', $nametypeSelect);
		self::createBlogOption('borderby',         _NP_WPSANDBOX_BLOGOPTION_BORDERBY, 'select',   'name', $orderbySelect);
		self::createBlogOption('bdirection',       _NP_WPSANDBOX_BLOGOPTION_BDIRECT,  'select',   'asc',  $directionSelect);
		self::createBlogOption('bookmarks',        _NP_WPSANDBOX_BLOGOPTION_BOOKMRKS, 'textarea', $bookmarkList);
		self::createBlogOption('syndicates',       _NP_WPSANDBOX_BLOGOPTION_FEEDLINK, 'textarea', $syndicateList);
	}

	// }}}
	// {{{ init()

	/**
	 * Initialize plugin
	 */
	public function init()
	{
		self::__construct();
	}

	// }}}

// }}}
// {{{ Private utility

/**
 * Utillities
 */

	// {{{ pluginCheck($pluginName)

	/**
	 * Plugin installed check
	 *
	 * @param string check plugin
	 * @ return mix installed:object not installed:bool
	 */
	protected function pluginCheck($pluginName)
	{
		global $manager;
		if ($manager->pluginInstalled('NP_' . $pluginName)) {
			return $manager->getPlugin('NP_' . $pluginName);
		} else {
			return false;
		}
	}

	// }}}
	// {{{ getSpecialSkinParts()

	/**
	 * Skin types not Nucleus builtin.
	 *
	 * Get skin-types of 'special skin parts'.
	 *
	 * @return array
	 */
	protected function getSpecialSkinParts($bid)
	{
		global $CONF, $manager;
		$bid   = intval($bid);
		$query = "SELECT stype "
			   . "FROM " . sql_table('skin')
			   . " WHERE stype NOT IN "
//			   . "('index', 'item', 'error', 'search', 'archive', 'archivelist', 'imagepopup', 'member',"
			   . "('index', 'item', 'error', 'search', 'archive', 'imagepopup', 'member',"
			   . " 'login', 'header', 'footer', 'sidebar', 'aboutcontents', 'linkscontents', 'commentform',"
			   . " 'archivecontents')"
			   . " AND sdesc = " . intval(SKIN::getIdFromName(self::$skin->name));
		$res   = sql_query($query);
		if (mysql_num_rows($res) > 0) {
			while ($row = mysql_fetch_array($res)) {
				$skintypes[strtolower($row['stype'])] = htmlspecialchars(ucfirst($row['stype']), ENT_QUOTES);
			}
			return $skintypes;
		}
	}

	// }}}
	// {{{ getPageListData($template)

	/**
	 * Return formatted Pages list
	 *
	 * @param aray template data
	 * @return string formatted list
	 */
	protected function getPageListData($pages, $template, $bid)
	{
		$ret = '';
		foreach ($pages as $pagetype => $pagename) {
			if ($pagetype == 'archivelist') {
				$pagelink = createArchiveListLink($bid);
			} else {
				$pagelink = createBlogIDLink($bid, array('special' => $pagetype));
			}
			$data = array('pagename' => $pagename,
						  'pagelink' => $pagelink,
						  'currflag' => ($pagetype == self::$skinType) ? ' current_page_item' : '',);
			$ret .= TEMPLATE::fill($template['Sandbox_PagesList_Body'], $data);
		}
		return $ret;
	}

	// }}}
	// {{{ includeLanguageFile()

	/**
	 * Language file include
	 */

	protected function includeLanguageFile()
	{
		$language = ereg_replace( '[\\|/]', '', getLanguageName());
		if (file_exists($this->getDirectory() . 'language/' . $language . '.php')) {
			include_once($this->getDirectory() . 'language/' . $language . '.php');
		} else {
			include_once($this->getDirectory() . 'language/english.php');
		}
	}

	// }}}

// }}}
// {{{ Skin/template variables

/**
 * Variables execute
 */

	// {{{ doSkinVar($skinType, $type, $extra = '')

	/**
	 * Skin variables
	 *
	 * @param string type of current skin
	 * @param string type of variable
	 * @param string argument of variable
	 */
	public function doSkinVar($skinType, $type, $extra = '')
	{
		if ($type == 'date' && $a = func_get_arg(3)) {
			$extra .= ', ' . $a;
		}
		if (method_exists(self::$parser, 'parse_' . $type)) {
			call_user_func_array(array(&self::$parser, 'parse_' . $type), array($extra));
		}
	}

	// }}}
	// {{{ doTemplateVar(&$item, $type, $extra = '')

	/**
	 * Template variables
	 *
	 * @param object current ITEM object
	 * @param string type of variable
	 * @param string argument of variable
	 */
	public function doTemplateVar(&$item, $type, $extra = '')
	{
		if ($type == 'date' && $a = func_get_arg(3)) {
			$extra .= ', ' . $a;
		}
		if (method_exists(self::$parser, 'parse_' . $type)) {
			call_user_func_array(array(&self::$parser, 'parse_' . $type), array($extra, $item));
		}
	}

	// }}}
	// {{{ doTemplateCommentsVar(&$item, &$comment, $type = 'commentClass', $extra)

	/**
	 * Comment template variables
	 *
	 * @param object current ITEM object
	 * @param object current COMMENT object
	 * @param string type of variable
	 * @param string argument of variable
	 */
	public function doTemplateCommentsVar(&$item, &$comment, $type = '', $extra = '')
	{
//		print_r($comment);
		if ($type == 'date' && $a = func_get_arg(4)) {
			$extra .= ', ' . $a;
		}
		if (method_exists(self::$parser, 'parse_' . $type)) {
			call_user_func_array(array(&self::$parser, 'parse_' . $type), array($extra, $item, $comment));
		}
	}

	// }}}

// }}}
// {{{ Plugin events

/**
 * Plugin event triggers
 */

	// {{{ parse_meta($b, $bid)

	/**
	 * Parse <%meta%> tag
	 *
	 * this method is only private access.
	 * Make 'WPSandBoxWPMETAEmulate' event occur.
	 *
	 * @param array {@see parse_meta()}
	 **/
	public function event_WPSandBoxWPMETAEmulate($data)
	{
		global $CONF;
		$data['meta']['WPSandBox'] = array('<a href="http://japan.nucleuscms.org" title="Powered by NucleusCMS">NucleusCMS</a>',
											  '<a href="' . $CONF['AdminURL'] . '" title="Admin area">Admin area</a>',);
	}

	// }}}
	// {{{ event_TemplateExtraFields(&$data)

	/**
	 * Plugin custom template
	 *
	 * New featur v3.40 or lator.
	 * Custom template data input to $data['fields'][PluginName] as array 'field name' => 'default'.
	 * For more information {@link http://forum.nucleuscms.org/viewtopic.php?p=87672 Skin specific values for Plugins}.
	 *
	 * param array {@see ADMIN::action_templateedit}
	 */
	public function event_TemplateExtraFields(&$data)
	{
		$data['fields']['NP_WPSandBox'] = array('Sandbox_PagesList_Menu'       => _NP_WPSANDBOX_TEMPLATE_PAGESLIST_MENU,
												'Sandbox_PagesList_header'     => _NP_WPSANDBOX_TEMPLATE_PAGESLIST_HEADER,
												'Sandbox_PagesList_Body'       => _NP_WPSANDBOX_TEMPLATE_PAGESLIST_BODY,
												'Sandbox_PagesList_Footer'     => _NP_WPSANDBOX_TEMPLATE_PAGESLIST_FOOTER,
												'Sandbox_SearchForm_Header'    => _NP_WPSANDBOX_TEMPLATE_SEARCHFORM_HEADER,
												'Sandbox_SearchForm_Body'      => _NP_WPSANDBOX_TEMPLATE_SEARCHFORM_BODY,
												'Sandbox_SearchForm_Footer'    => _NP_WPSANDBOX_TEMPLATE_SEARCHFORM_FOOTER,
												'Sandbox_Bookmarks_Header'     => _NP_WPSANDBOX_TEMPLATE_BOOKMARKS_HEADER,
												'Sandbox_Bookmarks_Body'       => _NP_WPSANDBOX_TEMPLATE_BOOKMARKS_BODY,
												'Sandbox_Bookmarks_Footer'     => _NP_WPSANDBOX_TEMPLATE_BOOKMARKS_FOOTER,
												'Sandbox_FeedList_Header'      => _NP_WPSANDBOX_TEMPLATE_FEEDLIST_HEADER,
												'Sandbox_FeedList_Body'        => _NP_WPSANDBOX_TEMPLATE_FEEDLIST_BODY,
												'Sandbox_FeedList_Footer'      => _NP_WPSANDBOX_TEMPLATE_FEEDLIST_FOOTER,
												'Sandbox_MetaData_Header'      => _NP_WPSANDBOX_TEMPLATE_METADATA_HEADER,
												'Sandbox_MetaData_Body'        => _NP_WPSANDBOX_TEMPLATE_METADATA_BODY,
												'Sandbox_MetaData_Footer'      => _NP_WPSANDBOX_TEMPLATE_METADATA_FOOTER,
												'SandBox_MetaData_Loggedin'    => _NP_WPSANDBOX_TEMPLATE_METADATA_LOGGEDIN,
												'SandBox_MetaData_NotLoggedin' => _NP_WPSANDBOX_TEMPLATE_METADATA_NOTLOGGEDIN,
												'SandBox_MetaData_register'    => _NP_WPSANDBOX_TEMPLATE_METADATA_REGISTER,
												'SandBox_MetaData_extra_Head'  => _NP_WPSANDBOX_TEMPLATE_METADATA_EXTRA_HEADER,
												'SandBox_MetaData_extra_Body'  => _NP_WPSANDBOX_TEMPLATE_METADATA_EXTRA_BODY,
												'SandBox_MetaData_extra_Foot'  => _NP_WPSANDBOX_TEMPLATE_METADATA_EXTRA_FOOTER,
												'SandBox_DailyArchive_Title'   => _NP_WPSANDBOX_TEMPLATE_DAILYARCHIVE_TITLE,
												'SandBox_DArchiveTitleFormat'  => _NP_WPSANDBOX_TEMPLATE_ACIVETITLEDATEFORMATD,
												'SandBox_MonthlyArchive_Title' => _NP_WPSANDBOX_TEMPLATE_MONTHLYARCHIVE_TITLE,
												'SandBox_MArchiveTitleFormat'  => _NP_WPSANDBOX_TEMPLATE_ACIVETITLEDATEFORMATM,
												);
	}

	// }}}
	// {{{ event_PreSendContentType($contentType, $charset, $pageType)

	/**
	 * Processing when 'PreSendContentType' event occurred
	 *
	 * @param string HTTP Content-Type
	 * @param string Name of charctor code set
	 * @param string Type of current skin
	 */
	public function event_PreSendContentType($data)
	{
		self::$contentType = $data['contentType'];
	}

	// }}}
	// {{{ event_InitSkinParse($data)

	/**
	 * Processing when 'InitSkinParse' event occurred
	 *
	 * @param array {@see SKIN::parse()}
	 */
	public function event_InitSkinParse($data)
	{
		global $startpos;
		if ($p = intRequestVar('page') > 1) {
			self::$page = $p;
		} elseif ($startpos > 0) {
			self::$page = $startpos;
		}
		self::$skin     = $data['skin'];
		self::$skinType = $data['type'];
	}

	// }}}
	// {{{ event_WPSandBoxDynamicSidebar($data)

	/**
	 * Processing when 'WPSandBoxDynamicSidebar' event occurred
	 *
	 * Dynamic Sidebar Widgets from WordPress
	 * Sidebar Widgets of WordPress was mounted on Nucleus.
	 *
	 * @param array {@see SandBoxParser::parse_dynamicsidebar()}
	 */
	public function event_WPSandBoxDynamicSidebar($data)
	{
		global $CONF, $blog;
		extract($data);
		if ($blog) {
			$b = &$blog;
		} else {
			global $manager;
			$b = &$manager->getBlog($CONF['DefaultBlog']);
		}
		$bid = $b->getID();
		if ($mode == 1) {
			if (self::getBlogOption($bid, 'showPageList') != 'no') {
				self::showSidebarPageList($b, $bid, $template);
			}
			if (self::getBlogOption($bid, 'showBlogList') != 'no') {
				self::showSidebarBlogList($b, $bid, $template);
			}
			if (self::getBlogOption($bid, 'showCategoryList') != 'no') {
				self::showSidebarCategoryList($b, $bid, $template);
			}
			if (self::getBlogOption($bid, 'showArchoveList') != 'no') {
				self::showSidebarArchoveList($b, $bid, $template);
			}
		} else {
			if (self::getBlogOption($bid, 'showSearchBox') != 'no') {
				self::showSidebarSearchBox($b, $bid, $template);
			}
			if (self::getBlogOption($bid, 'showBookmarkList') != 'no') {
				self::showSidebarBookmarkList($b, $bid, $template);
			}
			if (self::getBlogOption($bid, 'showFeedsList') != 'no') {
				self::showSidebarFeedsList($b, $bid, $template);
			}
			if (self::getBlogOption($bid, 'showMetaBox') != 'no') {
				self::showSidebarMetaBox($b, $bid, $template);
			}
		}
	}

	// }}}
	// {{{ event_WPSandBoxPrePageHead($data)

	/**
	 * Processing when 'WPSandBoxPrePageHead' event occurred
	 *
	 * @param array {@see SandBoxParser::parse_extrapagehead()}
	 */
	public function event_WPSandBoxPrePageHead($data)
	{
		global $CONF, $blog;
		if ($blog) {
			$b = &$blog;
		} else {
			global $manager;
			$b = &$manager->getBlog($CONF['DefaultBlog']);
		}
		switch ($data['skinType']) {
			case 'index':
				$data['extraPagehead'] .= '<link rel="bookmark" title="Nucleus" href="http://nucleuscms.org/" />
<link rel="archives" title="Archives" href="' . createArchiveListLink($b->getID()) . '" />
<link rel="top" title="Today" href="' . createBlogIDLink($b->getID()) . '" />';
				break;
			case 'item':
				global $itemidprev, $itemidnext;
				$data['extraPagehead'] .= '<link rel="archives" title="Archives" href="' . createArchiveListLink($b->getID()) . '" />
<link rel="top" title="Today" href="' . $CONF['IndexURL'] . '" />
<link rel="next" href="' . createItemLink($itemidnext) . '" title="Next Item" />
<link rel="prev" href="' . createItemLink($itemidprev) . '" title="Previous Item" />
<link rel="up" href="' . createBlogIDLink($b->getID()) . '" title="Today" />
<meta name="robots" content="all,noodp,noydir" />';
				break;
			case 'archive':
				global $itemidprev, $itemidnext;
				$data['extraPagehead'] .= '<link rel="archives" title="Archives" href="' . createArchiveListLink($b->getID()) . '" />
<link rel="top" title="Today" href="' . $CONF['IndexURL'] . '" />
<link rel="up" href="' . createBlogIDLink($b->getID()) . '" title="Today" />
<meta name="robots" content="all,noodp,noydir,NOINDEX,NOFOLLOW" />';
				break;
			case 'archivelist':
				global $itemidprev, $itemidnext;
				$data['extraPagehead'] .= '<link rel="archives" title="Archives" href="' . createArchiveListLink($b->getID()) . '" />
<link rel="top" title="Today" href="' . $CONF['IndexURL'] . '" />
<link rel="up" href="' . createBlogIDLink($b->getID()) . '" title="Today" />
<meta name="robots" content="all,noodp,noydir,NOINDEX,NOFOLLOW" />';
				break;
			case 'error':
				global $itemidprev, $itemidnext;
				$data['extraPagehead'] .= '<link rel="top" title="Today" href="' . $CONF['IndexURL'] . '" />
<link rel="up" href="' . createBlogIDLink($b->getID()) . '" title="Today" />
<meta name="robots" content="all,noodp,noydir,NOINDEX,NOFOLLOW" />';
				break;
			case 'member':
				global $itemidprev, $itemidnext;
				$data['extraPagehead'] .= '<link rel="top" title="Today" href="' . $CONF['IndexURL'] . '" />
<link rel="up" href="' . createBlogIDLink($b->getID()) . '" title="Today" />
<meta name="robots" content="all,noodp,noydir,NOINDEX,NOFOLLOW" />';
				break;
			case 'search':
				global $itemidprev, $itemidnext;
				$data['extraPagehead'] .= '<link rel="archives" title="Archives" href="' . createArchiveListLink($b->getID()) . '" />
<link rel="top" title="Today" href="' . $CONF['IndexURL'] . '" />
<link rel="up" href="' . createBlogIDLink($b->getID()) . '" title="Today" />';
				break;
		}
	}

	// }}}

// }}}
// {{{ Sidebar Widgets for NucleusCMS

/**
 * Dynamic Sidebar Widgets from WordPress
 */

	// {{{ showSidebarPageList()

	/**
	 * Show extra pages list
	 *
	 * Output extra pages name and link
	 */
	private function showSidebarPageList($b, $bid, $template)
	{
		global $manager;
		$template =& $manager->getTemplate($template);
		echo TEMPLATE::fill($template['Sandbox_PagesList_header'], array());
		$pages  = self::getSpecialSkinParts($bid);
		if (!is_array($pages)) {
			$pages = array($pages);
		}
		if (count($pages) < 1) {
			return;
		}
		$output = self::getPageListData($pages, $template, $bid);
		echo $output;
		echo TEMPLATE::fill($template['Sandbox_PagesList_Footer'], array());
	}

	// }}}
	// {{{ showSidebarBlogList()

	/**
	 * Show blogs list
	 *
	 * Output blogs link list
	 */
	private function showSidebarBlogList($b, $bid, $template)
	{
		$bnametype = self::getBlogOption($bid, 'bnametype');
		$orderby   = self::getBlogOption($bid, 'borderby');
		$direction = self::getBlogOption($bid, 'bdirection');
		$b->showBlogList($template, $bnametype, $orderby, $direction);
	}

	// }}}
	// {{{ showSidebarCategoryList()

	/**
	 * Show caregories list
	 *
	 * Output categories link list
	 */
	private function showSidebarCategoryList($b, $bid, $template)
	{
		$b->showCategoryList($template);
	}

	// }}}
	// {{{ showSidebarArchoveList()

	/**
	 * Show archives list
	 *
	 * Output archive link list
	 */
	private function showSidebarArchoveList($b, $bid, $template)
	{
		$b->showArchiveList($template);
	}

	// }}}
	// {{{ showSidebarSearchBox()

	/**
	 * Show search form
	 *
	 * Output search form box
	 */
	private function showSidebarSearchBox($b, $bid, $template)
	{
		global $manager, $CONF;
		$template =& $manager->getTemplate($template);
		echo TEMPLATE::fill($template['Sandbox_SearchForm_Header'], array());
		$data = array('self' => $CONF['Self'],
					  'blogid' => $bid,
					  'query' => htmlspecialchars(getVar('query'), ENT_QUOTES),
					  'searchform_submit' => _SEARCHFORM_SUBMIT);
		echo TEMPLATE::fill($template['Sandbox_SearchForm_Body'], $data);
		echo TEMPLATE::fill($template['Sandbox_SearchForm_Footer'], array());
	}

	// }}}
	// {{{ showSidebarBookmarkList()

	/**
	 * Show BLOG bookmarks
	 *
	 * Output bookmarks list by Blog admin.
	 */
	private function showSidebarBookmarkList($b, $bid, $template)
	{
		global $manager;
		$template  = &$manager->getTemplate($template);
		$bookmarks = preg_split('/(\r\n|\n|\r)/', self::getBlogOption($bid, 'bookmarks'));
		$linkcat   = 1;
		foreach ($bookmarks as $bookmark) {
			if (strpos($bookmark, ',') !== false) {
				list($href, $anchor) = explode(',', $bookmark);
				$data = array('href' => trim($href),
							  'text' => trim($anchor),);
				echo TEMPLATE::fill($template['Sandbox_Bookmarks_Body'], $data);
			} elseif (empty($bookmark)) {
				echo TEMPLATE::fill($template['Sandbox_Bookmarks_Footer'], array());
			} else {
				$data = array('linkcat' => $linkcat,
							  'heading' => trim($bookmark),);
				echo TEMPLATE::fill($template['Sandbox_Bookmarks_Header'], $data);
				$linkcat++;
			}
		}
		echo TEMPLATE::fill($template['Sandbox_Bookmarks_Footer'], array());
	}

	// }}}
	// {{{ showSidebarFeedsList()

	/**
	 * Show feed links list
	 *
	 * Output feed links
	 */
	private function showSidebarFeedsList($b, $bid, $template)
	{
		global $manager;
		$template = &$manager->getTemplate($template);
		$feeds    = preg_split('/(\r\n|\n|\r)/', self::getBlogOption($bid, 'syndicates'));
		echo TEMPLATE::fill($template['Sandbox_FeedList_Header'], array());
		foreach ($feeds as $feed) {
			if (!empty($feed)) {
				list($type, $href, $title) = explode(',', $feed);
				$data = array('feedtype'  => trim($type),
							  'feedurl'   => trim($href),
							  'feedtitle' => trim($title),);
				echo TEMPLATE::fill($template['Sandbox_FeedList_Body'], $data);
			}
		}
		echo TEMPLATE::fill($template['Sandbox_FeedList_Footer'], array());
	}

	// }}}
	// {{{ showSidebarMetaBox()

	/**
	 * Show META infomations
	 *
	 * Output META box.
	 * Link to ligin form, admin area, and etc.
	 */
	private function showSidebarMetaBox($b, $bid, $template)
	{
		global $manager, $CONF, $member;
		$template = &$manager->getTemplate($template);
		$outMeta  = array($b,
						  $bid,
						  $template);
		$metadata = call_user_func_array(array(&self::$parser, 'parse_meta'), $outMeta);
		echo TEMPLATE::fill($template['Sandbox_MetaData_Header'], array());
		if (($CONF['AllowMemberCreate']) && @file_exists($CONF['IndexURL'] . 'createaccount.php')) {
			$data     = array('registerlink' => $CONF['IndexURL'] . 'createaccount.php');
			$register = TEMPLATE::fill($template['SandBox_MetaData_register'], $data);
		} else {
			$register = '';
		}
		if ($member->isLoggedIn()) {
			$url      = serverVar('REQUEST_URI');
			$url      = $url . ((strpos($url, '?') !== false) ? '&amp;' : '?') . 'action=logout';
			$data     = array('handlename'   => $member->getRealName(),
							  'loginoutlink' => $url);
			$loginout = TEMPLATE::fill($template['SandBox_MetaData_Loggedin'], $data);
		} else {
			$data     = array(createBlogIDLink($bid, array('special' => 'loginform')));
			$loginout = TEMPLATE::fill($template['SandBox_MetaData_NotLoggedin'], $data);
		}
		$data = array('register' => $register,
					  'loginout' => $loginout,
					  'metadata' => $metadata,);
		echo TEMPLATE::fill($template['Sandbox_MetaData_Body'], $data);
		echo TEMPLATE::fill($template['Sandbox_MetaData_Footer'], array());
	}

	// }}}

// }}}
// {{{ Processing 'IF'

	// {{{ doIf()

	/**
	 * Check condition
	 *
	 * If 'key' eq 'value' or 'key' eq true return 'true'
	 *
	 * @param string check it.
	 * @param string key is comp it.
	 * @return bool true or false
	 */
	public function doIf($key, $value)
	{
		global $manager, $CONF, $blogid, $itemid;
		$condition = false;
		if (!$blogid) {
			$blogid = $CONF['DefaultBlog'];
		}
		$blog = &$manager->getBlog(intval($blogid));
		if (self::$skinType == 'item') {
			$item = &$manager->getItem(intval($itemid), 0, 0);
		}
		switch ($key) {
			case 'itemopen':
				if (!$item['closed'] && $blog->commentsEnabled()) {
					$condition = true;
				}
				break;
			case 'archivetype':
				if (self::$skinType != 'archive') return false;
				global $archive, $manager;
				if (empty($value)) {
					$value = 'Sandbox/sidebar';
				}
				$tpl = $manager->getTemplate($value);
				sscanf($archive, '%d-%d-%d', $y, $m, $d);
				$y = intval($y);
				$m = intval($m);
				$d = intval($d);
				if (!empty($y) && !empty($m) && !empty($d)) {
					$tDate = date($tpl['SandBox_DArchiveTitleFormat'], mktime(0, 0, 0, $m, $d, $y));
					echo TEMPLATE::fill($tpl['SandBox_DailyArchive_Title'], array('date' => $tDate));
					$condition = true;
				} elseif (!empty($y) && !empty($m) && empty($d)) {
					$tDate = date($tpl['SandBox_MArchiveTitleFormat'], mktime(0, 0, 0, $m, $d, $y));
					echo TEMPLATE::fill($tpl['SandBox_MonthlyArchive_Title'], array('date' => $tDate));
					$condition = true;
				}
				break;
			case 'search':
				global $query, $blog;
				$highlight = $query;
				$condition = quickQuery($blog->getSqlSearch($query, 0, $highlight, 'count'));
				break;
		}
		return $condition;
	}

	// }}}

// }}}

}


abstract class WPSandBox extends NP_WPSandBox
{

// {{{ abstract function

/**
 * Variables parse functions abstraction
 */

	// {{{ parse_dynamicsidebar($extra)

	/**
	 * Parse skinvar 'dynamicsidebar'
	 *
	 * Skin variable parser.
	 * <%WPSandBax(dynamicsidebar, n)%>
	 * 'n' is '1' or larger int.
	 * Make 'WPSandBoxDynamicSidebar' event occur.
	 *
	 * @param int skinvar 2nd argument
	 */
	abstract protected function parse_dynamicsidebar($extra);

	// }}}
	// {{{ parse_sandboxbodyclass()

	/**
	 * Parse skinvar 'sandboxbodyclass'
	 *
	 * Skin variable parser.
	 * <%WPSandBax(sandboxbodyclass)%>
	 * Output micro format class to <BODY> tag.
	 */
	abstract protected function parse_sandboxbodyclass();

	// }}}
	// {{{ parse_globalnavi($mode = 'global')

	/**
	 * Parse skinvar 'sandboxbodyclass'
	 *
	 * Skin variable parser.
	 * <%WPSandBax(sandboxbodyclass)%>
	 * Output micro format class to <BODY> tag.
	 */
	abstract protected function parse_globalnavi($mode = 'global');

	// }}}
	// {{{ parse_text($extra, $item, $comment)

	/**
	 * Parse skinvar 'text'
	 *
	 * Skin variable parser.
	 * <%WPSandBax(text)%>
	 * Output defined sentens.
	 */
	abstract protected function parse_text($extra, $item = false, $comment = false);

	// }}}
	// {{{ parse_extrapagehead()

	/**
	 * Parse skinvar 'extrapagehead'
	 *
	 * Skin variable parser.
	 * <%WPSandBax(extrapagehead)%>
	 * Make 'WPSandBoxPrePageHead' event occur.
	 * And output extra page head
	 */
	abstract protected function parse_extrapagehead();

	// }}}
	// {{{ parse_extrapagefoot()

	/**
	 * Parse skinvar 'extrapagefoot'
	 *
	 * Skin variable parser.
	 * <%WPSandBax(extrapagefoot)%>
	 * Make 'WPSandBoxPrePageFoot' event occur.
	 * And output extra page foot
	 */
	abstract protected function parse_extrapagefoot();

	// }}}
	// {{{ parse_contenttype()

	/**
	 * Parse skinvar 'contenttype'
	 *
	 * Skin variable parser.
	 * <%WPSandBax(contenttype)%>
	 * Output HTML Content-Type fot <meta> tag.
	 */
	abstract protected function parse_contenttype();

	// }}}
	// {{{ parse_stylesheeturl()

	/**
	 * Parse skinvar 'stylesheeturl'
	 *
	 * Skin variable parser.
	 * <%WPSandBax(stylesheeturl)%>
	 * Output URL of BLOG specified Cascading Style Sheets file.
	 */
	abstract protected function parse_stylesheeturl();

	// }}}
	// {{{ parse_xmldeclaration()

	/**
	 * Parse skinvar 'stylesheeturl'
	 *
	 * Skin variable parser.
	 * <%WPSandBax(parse_xmldeclaration)%>
	 * Output XML declaration.
	 */
	abstract protected function parse_xmldeclaration();

	// }}}
	// {{{ parse_meta($b, $bid, $template)

	/**
	 * Parse <%meta%> tag
	 *
	 * Make 'WPSandBoxWPMETAEmulate' event occur.
	 *
	 * @param object current BLOG object
	 * @param int current blog ID
	 * @param string template fo metadata
	 * @return string metadata
	 **/
	abstract protected function parse_meta($b, $bid, $template);

	// }}}
	// {{{ parse_date()

	/**
	 * parse template/templatecomment var 'date'
	 *
	 * Template variable parser.
	 * <%WPSandBax(date, format)%>
	 * Output formatted date via 'date' function.
	 * You can use ',' in format.
	 *
	 * @param string date/time format for 'date()' function
	 * @param object current item
	 */
	abstract protected function parse_date($extra, $item = '', $comment = '');

	// }}}
	// {{{ parse_sandboxpostclass($extra, $item)

	/**
	 * Parse templatevar 'sandboxpostclass'
	 *
	 * Template variable parser.
	 * <%WPSandBax(sandboxpostclass)%>
	 * Output micro format class to each post's <DIV> tags.
	 *
	 * @param string skinvar 2nd argument
	 * @param object current item object
	 */
	abstract protected function parse_sandboxpostclass($extra, $item);

	// }}}
	// {{{ parse_sandboxpostclass($extra, $item)

	/**
	 * Parse skinvar 'currentblog'
	 *
	 * Template variable parser.
	 * <%WPSandBax(currentblog, EXTRA)%>
	 * Output currentblog settings.
	 *
	 * @param string skinvar 2nd argument
	 */
	abstract protected function parse_currentblog($extra);

	// }}}

// }}}


}
